/**
 * @project: fridahook
 * @package:
 * @Description: 新氧app _sign 和 xy_sign 参数校验
 * @Author: ts.
 * @Email: 
 * @Date: 2021-05-27 18:50:56
 */


function showStacks() {
    Java.perform(function () {
        console.log("----------------------------------------------------------------------------------------------\n");
        console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()));
        console.log("----------------------------------------------------------------------------------------------\n");
    });
}


Java.perform(function () {


    /**
     * 调试 hook 签名函数以及参数和返回值, 这里hook不到，改为xposed 尝试一下.
     * @type {Java.Wrapper<{}>}
     * 堆栈信息是这样的,所以一开始我猜的那个是地方是没问题的,但是frida 一直hook不上, 该app返Xposed Hook,重新hook就可以hook上了
     java.lang.Exception
     at java.util.TreeMap.put(Native Method)
     at com.soyoung.component_data.common_api.AppApiCommonParameter.getCommonParasm(SourceFile:52)
     at com.soyoung.component_data.common_api.AppApiCommonParameter.getCommonParasm(SourceFile:1)
     at com.soyoung.library_network.base_api.AppApiHelper.getCommonParasm(SourceFile:1)
     at com.soyoung.library_network.base_api.AppApiHelper$1.apply(SourceFile:2)
     at com.soyoung.library_network.base_api.AppApiHelper$1.apply(SourceFile:1)
     at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onNext(SourceFile:2)
     at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeOnObserver.onNext(SourceFile:1)
     at io.reactivex.internal.operators.observable.ObservableScalarXMap$ScalarDisposable.run(SourceFile:2)
     at io.reactivex.internal.operators.observable.ObservableJust.subscribeActual(SourceFile:3)
     at io.reactivex.Observable.subscribe(SourceFile:14)
     at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(SourceFile:1)
     at io.reactivex.Scheduler$DisposeTask.run(SourceFile:2)
     at io.reactivex.internal.schedulers.ScheduledRunnable.run(SourceFile:2)
     at io.reactivex.internal.schedulers.ScheduledRunnable.call(SourceFile:1)
     at java.util.concurrent.FutureTask.run(FutureTask.java:266)
     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
     at java.lang.Thread.run(Thread.java:919)

     */
    // let map = Java.use("java.util.TreeMap");
    // map.put.implementation = function (v1, v2) {
    //     if (v1== "_sign" || v1 == "xy_sign"){
    //         console.log("key: " + v1 + "\tvalue: " + v2);
    //         showStacks();
    //     }
    //     return this.put(v1,v2);
    // }

    /**
     * hook 组装参数函数. 需要注意的是 请求参数中如果需要翻页,必须和前一页的device_id保持一致 否则会一直返回第一页数据
     * @type {Java.Wrapper<{}>}
     */
    let common = Java.use("com.soyoung.component_data.common_api.AppApiCommonParameter")
    common.getCommonParasm.overload('java.util.HashMap', 'java.lang.String').implementation = function (v1, v2) {
        console.log("v1:   " + v1);
        console.log("v2:   " + v2);
        var keyset = v1.keySet();
        var it = keyset.iterator();
        while(it.hasNext()){
            var keystr = it.next().toString();
            var valuestr = v1.get(keystr);
            console.log("key:  " + keystr +"\tvalue:   " + valuestr)
        }
        const res = this.getCommonParasm(v1,v2);
        console.log("res:   " + res);
        return res;
    }

    /**
     * hook xy_sign 生成参数入口函数
     * @type {Java.Wrapper<{}>}
     */
    // let param = Java.use("com.soyoung.component_data.common_api.AppApiCommonParameter")
    // param.paramsNewSign.implementation = function (v1){
    //     console.log("↓↓↓================================================================↓↓↓")
    //     console.log("v1:   " + v1);
    //     const res = this.paramsNewSign(v1);
    //     console.log("res:   " + res);
    //     console.log("↑↑↑================================================================↑↑↑")
    //     return res;
    // }

    /**
     * hook navite 函数 查看调用前和调用后的参数是否一致
     * @type {Java.Wrapper<{}>}
     */
    // let O0 = Java.use("oO.oz.o0s.o.O0")
    // O0.o0o.implementation = function (v1, v2, v3, v4) {
    //     console.log("***************************************************************")
    //     console.log(JSON.stringify(v2))
    //     console.log(JSON.stringify(v3))
    //     console.log(JSON.stringify(v4))
    //     let res = O0.o0o(v1,v2,v3,v4);
    //     console.log("----------------------------------------------------------------")
    //     console.log(JSON.stringify(v2))
    //     console.log(JSON.stringify(v3))
    //     console.log(JSON.stringify(v4))
    //     console.log("***************************"+res+"************************************")
    //     return res;
    // }

})